<script setup>
/*
Vue3中第二种响应式状态方案：reactive
  let state = reactive({
    xxx:xxx,
    ...
  })
  + 执行一次，返回一个状态对象「proxy对象」，其中包含需要的状态
  + 基于ES6中的 Proxy 实现数据劫持的「get/set/deleteProperty/has/ownKeys」
  + 后期在JS或者视图中，都是基于 state.xxx 去获取和操作状态值

Vue3中取消了Vue2中的filters过滤器
  + 我们可以在Vue3的项目中，基于vue2的语法使用过滤器
  + 也可以写一个普通方法，在视图渲染的时候，把方法执行，模拟出过滤器的效果 「推荐」
 */
import {
  reactive,
  watch,
  watchEffect,
  isProxy,
  readonly,
  toRef,
  toRefs,
  isReactive
} from "vue";

let state = reactive({
  supNum: 10,
  oppNum: 5,
  ratio: "--",
});
const change = (type) => {
  type === "sup" ? state.supNum++ : state.oppNum++;
};

// console.log(isProxy(state)); //true 检测某个值是否是基于Proxy代理的
// console.log(isProxy(state.supNum)); //false
// state = readonly(state); //把一个state/RefImpl对象变为只读对象
// console.log(toRefs(state));
// console.log(toRef(state.supNum)); //把state中每一项(或某一项)变为ObjectRefImpl对象 
// isReactive:检测是否是基于reactive创建出来的对象

/*
Vue3中的监听器：
  watchEffect:第一次渲染会执行一次，把函数用到的状态自动进行依赖和监听，当依赖状态发生改变，函数会重新执行
    watchEffect(()=>{
      ...
    });

  watch:监听现有状态的改变，从而处理一些事情
    watch(state,()=>{ ... });  监听整个state，其中任意状态改变都会触发执行「不常用的，可能导致死递归」
    watch(RefImpl,()=>{ ... });  也可以监听REF对象
    watch(  监听state中的某个状态值改变，则需要写成一个函数
      ()=>state.supNum,
      ()=>{ ... }
    )
    watch(xxx,函数,{
       immediate: true, //立即执行 默认false
       deep: true, //深度监听 默认false
    })
 */
const handler = () => {
  let { supNum, oppNum } = state,
    total = supNum + oppNum;
  state.ratio = total === 0 ? "--" : ((supNum / total) * 100).toFixed(2) + "%";
};
watch(() => state.supNum, handler, {
  immediate: true,
  deep: true,
});
watch(() => state.oppNum, handler);

/* watch(state, () => {
  let { supNum, oppNum } = state,
    total = supNum + oppNum;
  state.ratio = total === 0 ? "--" : ((supNum / total) * 100).toFixed(2) + "%";
}); */

/* watchEffect(() => {
  let { supNum, oppNum } = state,
    total = supNum + oppNum;
  state.ratio = total === 0 ? "--" : ((supNum / total) * 100).toFixed(2) + "%";
}); */
</script>

<template>
  <div class="vote-box">
    <div class="header">
      <h3 class="title">Vue3比Vue2更加的好用</h3>
      <span>{{ state.supNum + state.oppNum }}</span>
    </div>

    <div class="main">
      <p>支持人数：{{ state.supNum }}人</p>
      <p>反对人数：{{ state.oppNum }}人</p>
      <p>支持比率：{{ state.ratio }}</p>
    </div>

    <div class="footer">
      <el-button type="primary" @click="change('sup')">支持</el-button>
      <el-button type="danger" @click="change('opp')">反对</el-button>
    </div>
  </div>
</template>

<style lang="less" scoped>
.vote-box {
  box-sizing: border-box;
  margin: 0 auto;
  padding: 10px;
  width: 300px;
  border: 1px solid #ddd;

  .header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    border-bottom: 1px dashed #ddd;

    .title {
      line-height: 40px;
      font-size: 18px;
    }

    span {
      font-size: 18px;
      color: lightcoral;
    }
  }

  .main {
    margin: 10px 0;
    p {
      line-height: 30px;
      font-size: 14px;
    }
  }
}
</style>